package com.cmbc.connect;

import org.budo.cmbc.direct.sdk.CMBCDecryptKitDelegate;
import org.springframework.util.Base64Utils;

import lombok.extern.slf4j.Slf4j;

/**
 * @author lmw
 */
@Slf4j
public class SM2Encrypter {
    // 实例化工具类
    private CMBCDecryptKitDelegate decryptKit;

    public SM2Encrypter(String cmbcPublicCertFile, String userPrivateFile, String userPrivateFilePassword) {
        // 初始化证书信息，同一个对象初始化了该信息之后在没有使用反初始化之前都会使用该证书，只需要执行一次初始化
        try {
            // 成功返回0，失败返回错误码
            decryptKit = new CMBCDecryptKitDelegate();
            decryptKit.Initialize(userPrivateFile, userPrivateFilePassword, cmbcPublicCertFile);
        } catch (Throwable e) {
            throw new RuntimeException("#23 e=" + e, e);
        }
    }

    /**
     * 反初始化，销毁工具类中的证书信息
     */
    public void unInit() {
        try {
            decryptKit.Uninitialize();
        } catch (Throwable e) {
            log.error("#36 e=" + e, e);
        }
    }

    /**
     * 消息签名&加密
     */
    public String encryptAndSignMessage(String message) throws Throwable {
        if (null == message) {
            throw new RuntimeException(10001 + ", sign and encrypt message:message is null");
        }

        // 构造带签名的信息，必须是base64格式
        String userPlainBase64Text = Base64Utils.encodeToString(message.getBytes("UTF-8"));
        // 调用工具类，返回签名加密结果
        String userEnvelopebase64Message = decryptKit.SignAndEncryptMessage(userPlainBase64Text);
        return userEnvelopebase64Message;
    }

    /**
     * 消息解密&验签
     */
    public String decryptAndVerifyMessage(String envelop) throws Throwable {
        if (null == envelop) {
            throw new RuntimeException(10002 + ", decrypt message:envelop is null");
        }

        // 调用工具类，返回解密验签结果，base64格式
        String userSourceBase64Text = decryptKit.DecryptAndVerifyMessage(envelop);
        String userSourceText = new String(Base64Utils.decode(userSourceBase64Text.getBytes()), "UTF-8");
        return userSourceText;
    }
}
